/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package extension.room.tan;

import com.smartfoxserver.v2.entities.Room;
import com.smartfoxserver.v2.entities.User;
import extension.game.room.Game;
import extension.game.room.Player;
import extension.game.zone.Flag;
import extension.room.analyse.Card;
import java.util.LinkedList;
import java.util.List;
import log.Debug;

/**
 *
 * @author daz
 */
public class TanGame extends Game {

    public static final int ATTACK = 0;
    public static final int DEFENSE = 1;
    private TanExtension tanExtension;
    private TanPlayer[] listPlayers;
    private TanResponse tanResponse;
    private int lastBlock;
    private List<Integer> listCardOnTable;
    private int fightState;
//    private int currentCard;
    private int masterCard;
    private int currentRank;
    private boolean isFinishMatch;
    private List<Integer> listRegisterAttack;
    private int defenseTurn;
    private int startAttack;
    private int currentAttackCard;
    private int currentAttackTurn;
    private int finishRound;
    private boolean canGetMoreCard;
    private boolean isFighted;
    private int numberCardRemains;

    TanGame(TanExtension tanExtension, int roomId) {
        super(tanExtension.getParentRoom(), roomId);
        this.tanExtension = tanExtension;
        listPlayers = new TanPlayer[maxPlayer];
        this.tanResponse = tanExtension.getResponse();
        numberDealCard = 8;
        lastBlock = -1;
        listCardOnTable = new LinkedList<Integer>();
        currentAttackCard = -1;
        listRegisterAttack = new LinkedList<Integer>();
        canGetMoreCard = true;
        if (Debug.isDebug) {
//            numberDealCard = 3;
        }
    }

    public void addAttacker(int id) {
        if (id == gameTurn || listPlayers[id].getAttackState() == TanPlayer.DEFENSE || listPlayers[id].getNumberCardInHands() <= 0) {
            return;
        }
        boolean isAdded = false;
        for (Integer playerId : listRegisterAttack) {
            if (playerId.equals(id)) {
                isAdded = true;
                break;
            }
        }
        if (!isAdded) {
            listRegisterAttack.add(id);
        }
    }

    @Override
    public TanPlayer addPlayer(String name, long money, User user) {
        TanPlayer player = new TanPlayer(name, money, numberPlayers);
        player.setUser(user);
        if (numberPlayings <= 0 || numberPlayers <= 0) {
            isPlay = false;
        }
        if (numberPlayers < maxPlayer) {
            int seatPos = -1;
            for (int i = 0; i < maxPlayer; i++) {
                if (listPlayers[i] == null) {
                    seatPos = i;
                    listPlayers[seatPos] = player;
                    listPlayers[seatPos].setSeatPos(seatPos);
                    if (isPlay) {
                        listPlayers[seatPos].setState(TanPlayer.NOT_READY);
                    } else {
                        numberPlayings++;
                    }
                    break;
                }
            }
            if (numberPlayings == 1 && seatPos > -1) {
                listPlayers[seatPos].isHost = true;
                tableHost = seatPos;
            }
            numberPlayers++;
        } else {
            player.setSeatPos(-1);
        }

        if (!isPlay && listPlayers[tableHost] == null) {
            for (int i = 0; i < maxPlayer; i++) {
                if (listPlayers[i] != null) {
                    listPlayers[i].isHost = true;
                    tableHost = i;
                    break;
                }
            }
        }
        addTableInfo();
        Debug.d("number playing when add:" + numberPlayings);
        return player;
    }

    @Override
    protected void addTableInfo() {
        List<String> listPlayerNames = new LinkedList<String>();
        List<Integer> listPlayerPositions = new LinkedList<Integer>();
        for (int i = 0; i < listPlayers.length; i++) {
            if (listPlayers[i] != null) {
                if (listPlayers[i].getState() != TanPlayer.PLAYING) {
                    listPlayerPositions.add(0);
                } else {
                    listPlayerPositions.add(1);
                }
                listPlayerNames.add(listPlayers[i].getName());
            } else {
                listPlayerPositions.add(-1);
                listPlayerNames.add("0");
            }
        }

        room.setProperty(Flag.NUMBER_PLAYER, numberPlayings);
        room.setProperty(Flag.ROOM_PLAYER_NAME, listPlayerNames);
        room.setProperty(Flag.ROOM_PLAYER_POS, listPlayerPositions);
        Room lobbyRoom = tanExtension.getParentZone().getRoomByName("The Lobby");
        List<User> listSend = lobbyRoom.getUserList();
        for (User u : listSend) {
            String groupView = (String) u.getProperty(Flag.GROUP_NAME);
            if (groupView.equals(room.getGroupId())) {
                tanResponse.sendTableInfo(room.getName(), listPlayerNames, listPlayerPositions, lobbyRoom.getUserList());
            }
        }
    }

    @Override
    public void sendTableInfo(List<String> listNames, List<Long> listMoneys, List<Integer> listStates, Player player, User user) {
        this.tanResponse.sendTableInfo(listNames, listMoneys, listStates, betMoney,
                isPlay, tableHost, player.getSeatPos(), player.getTotalMoney(), user);
    }

    @Override
    public void updateReadyState() {
        for (int i = 0; i < maxPlayer; i++) {
            if (listPlayers[i] != null && listPlayers[i].getState() == TanPlayer.READY) {
                listPlayers[i].setState(TanPlayer.NOT_READY);
                tanResponse.sendReadyState(i, TanPlayer.NOT_READY, 1);
            }
        }
    }

    @Override
    public long removePlayer(int leaveId) {
        long playerMoney = 0;
        numberPlayers--;
        if (listPlayers[leaveId] != null) {
            if ((listPlayers[leaveId].getState() == TanPlayer.PLAYING && isPlay)
                    || (!isPlay)) {
                playerMoney = listPlayers[leaveId].getMoney() + listPlayers[leaveId].getTotalMoney();
                listPlayers[leaveId] = null;
                numberPlayings--;
                Debug.d("number playing when remove :" + numberPlayings);
                if (leaveId == tableHost) {
                    updateTableHost();
                }
                if (isPlay) {
                    penaltyMoney += betMoney * 5;
                    if (numberPlayings < 2) {
                        onFinishMatch();
                    } else {
                        if (gameTurn == leaveId) {
                            nextTurn();
                        }
                    }
                } else {
                    int numberReadys = 0;
                    for (int i = 0; i < maxPlayer; i++) {
                        if (listPlayers[i] != null && listPlayers[i].getState() == TanPlayer.READY) {
                            numberReadys++;
                        }
                    }
                    if (numberReadys == numberPlayings) {
                        startGame();
                    } else if (numberReadys == numberPlayers - 1) {
                        setIsHostTimeOut(true);
                        tanResponse.sendTimeCount(tableHost);
                    }
                }
                if (numberPlayers <= 0) {
                    reset();
                }

            } else {
                playerMoney = listPlayers[leaveId].getMoney() + listPlayers[leaveId].getTotalMoney();
                listPlayers[leaveId] = null;
            }
        }
        addTableInfo();
        return playerMoney;
    }

    @Override
    public void sendTimeCount(int host) {
        this.tanResponse.sendTimeCount(host);
    }

    @Override
    public void updateTableHost() {
        for (int i = 0; i < maxPlayer; i++) {
            if (listPlayers[i] != null) {
                tableHost = i;
                listPlayers[i].isHost = true;
                if (isPlay) {
                    tanResponse.sendUpdateTableHost(i, 1);
                } else {
                    tanResponse.sendUpdateTableHost(i, 0);
                    updateReadyState();
                }
                break;
            }
        }
    }

    @Override
    public void sendUpdateTableHost(int newHost, int isContinue) {
        this.tanResponse.sendUpdateTableHost(newHost, isContinue);
    }

    @Override
    public int changePlayerState(int readyId) {
        if (listPlayers[readyId] != null) {
            return listPlayers[readyId].changeState();
        }
        return -1;
    }

    @Override
    public int countNumberReady() {
        int result = 0;
        for (int i = 0; i < maxPlayer; i++) {
            if (listPlayers[i] != null && listPlayers[i].getState() == Player.READY) {
                result++;
            }
        }
        return result;
    }

    @Override
    public void dealCard() {
        dealer.shuffleCard();
        lastBlock = -1;
        if (winnerId == -1 || listPlayers[winnerId] == null) {
            for (int i = 0; i < maxPlayer; i++) {
                if (listPlayers[i] != null) {
                    gameTurn = i;
                    break;
                }
            }
        }
        for (int i = 0; i < maxPlayer; i++) {
            if (listPlayers[i] != null) {
                listPlayers[i].resetCard();
                if (listPlayers[i].getState() == TanPlayer.READY) {
                    for (int j = 0; j < numberDealCard; j++) {
                        int cardId = dealer.nextCard();
                        listPlayers[i].addCard(cardId);
                    }
                    listPlayers[i].updateNumberCardInHand();
                    tanResponse.sendDealCard(listPlayers[i].getListCardIds(), listPlayers[i].getUser());
                    listPlayers[i].setState(TanPlayer.PLAYING);
                    logShowSet(listPlayers[i].getName(), listPlayers[i].getListCardIds());
                }
            }
        }
        if (winnerId != -1) {
            gameTurn = winnerId;
        }

        for (int i = gameTurn + 1; i < gameTurn + maxPlayer; i++) {
            int checkTurn = i % maxPlayer;
            if (listPlayers[checkTurn] != null && listPlayers[checkTurn].getState() == TanPlayer.PLAYING) {
                defenseTurn = checkTurn;
                break;
            }
        }

        startAttack = gameTurn;
        currentAttackTurn = gameTurn;
        fightState = ATTACK;
        canGetMoreCard = true;
        isPlay = true;
        listPlayers[gameTurn].setAttackState(TanPlayer.ATTACKING);
        tanResponse.sendFirstTurn(gameTurn, defenseTurn, -1, tanExtension.getParentRoom().getUserList());
    }

    public int getRankPlayer(int playerPos) {
        listPlayers[playerPos].setRank(currentRank);
        listPlayers[playerPos].setState(TanPlayer.FINISH);
        listPlayers[playerPos].setAttackState(TanPlayer.SKIP);
        if (currentRank == 0) {
            winnerId = gameTurn;
        }

        currentRank++;
        if (currentRank == numberPlayings - 1) {
            isFinishMatch = true;
        }
        return currentRank - 1;
    }

    private void doFinishRound() {
        List<Integer> listMissings = new LinkedList<Integer>();
        List<Integer> listNumberCardInHand = new LinkedList<Integer>();
        for (int i = 0; i < maxPlayer; i++) {
            if (listPlayers[i] != null && listPlayers[i].getState() == TanPlayer.PLAYING) {
                int numberCardMissing = numberDealCard - listPlayers[i].getNumberCardInHands();
                if (numberCardMissing > 0) {
                    List<Integer> listAdditonalCard = new LinkedList<Integer>();
                    for (int j = 0; j < numberCardMissing; j++) {
                        int cardId = dealer.nextCard();
                        if (cardId != -1) {
                            listAdditonalCard.add(cardId);
                        } else if (canGetMoreCard) {
                            listAdditonalCard.add(masterCard);
                            canGetMoreCard = false;
                        } else {
                            break;
                        }
                    }
                    Debug.d(listPlayers[i].getName() + " more card");
                    logShowSet(listPlayers[i].getName(), listAdditonalCard);
                    listPlayers[i].addCard(listAdditonalCard);
                    listPlayers[i].updateNumberCardInHand();
                    tanResponse.sendAdditonalCard(listAdditonalCard, listPlayers[i].getUser());
                    listMissings.add(listAdditonalCard.size());
                } else {
                    listMissings.add(0);
                }
                listNumberCardInHand.add(listPlayers[i].getNumberCardInHands());
                if (listPlayers[i].getNumberCardInHands() <= 0 && listPlayers[i].getState() == TanPlayer.PLAYING) {
                    int rank = getRankPlayer(i);
                    tanResponse.sendFightAll(rank, i, numberPlayers - numberPlayings);
                }
            } else {
                listMissings.add(-1);
                listNumberCardInHand.add(-1);
            }
        }
        tanResponse.sendUpdateCardDown(listMissings, listNumberCardInHand, room.getUserList());
        numberCardRemains = (canGetMoreCard ? dealer.getSize() + 1 : 0);
        tanResponse.sendNumberCardRemain(numberCardRemains, room.getUserList());
        Debug.d("card remain :" + numberCardRemains);

        for (int i = startAttack + 1; i < startAttack + maxPlayer; i++) {
            int checkTurn = i % maxPlayer;
            if (listPlayers[checkTurn] != null
                    && listPlayers[checkTurn].getState() == TanPlayer.PLAYING
                    && listPlayers[checkTurn].getAttackState() != TanPlayer.DEFENSE_LOST) {
                currentAttackTurn = checkTurn;
                break;
            }
        }

        for (int i = currentAttackTurn + 1; i < currentAttackTurn + maxPlayer; i++) {
            int checkTurn = i % maxPlayer;
            if (listPlayers[checkTurn] != null && listPlayers[checkTurn].getState() == TanPlayer.PLAYING) {
                defenseTurn = checkTurn;
                break;
            }
        }

        for (int i = defenseTurn + 1; i < defenseTurn + maxPlayer - 1; i++) {
            int checkTurn = i % maxPlayer;
            if (listPlayers[checkTurn] != null
                    && listPlayers[checkTurn].getState() == TanPlayer.PLAYING) {
                listPlayers[checkTurn].setAttackState(TanPlayer.WAIT_ATTACK);
            }
        }
        startAttack = currentAttackTurn;
        gameTurn = currentAttackTurn;
        listPlayers[currentAttackTurn].setAttackState(TanPlayer.ATTACKING);
        listPlayers[defenseTurn].setAttackState(TanPlayer.DEFENSE);
        lastBlock = -1;
        finishRound = 1;
        listCardOnTable.clear();
        fightState = ATTACK;
        Debug.d("finish round");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
        }
        tanResponse.sendFinishRound();

        Debug.d(listPlayers[defenseTurn].getName() + " defense");
    }

    @Override
    public void nextTurn() {
        if (numberPlayings >= 2) {
            fightState = (currentAttackCard == -1 ? ATTACK : DEFENSE);
            List<Integer> listSuggestCards = new LinkedList<Integer>();
            if (fightState == ATTACK) {
                if (listPlayers[currentAttackTurn].getAttackState() == TanPlayer.ATTACKING) {
                    gameTurn = currentAttackTurn;
                } else if (!listRegisterAttack.isEmpty()) {
                    currentAttackTurn = listRegisterAttack.remove(0);
                    gameTurn = currentAttackTurn;
                    listPlayers[currentAttackTurn].setAttackState(TanPlayer.ATTACKING);
                } else {
                    doFinishRound();
                }
                if (!listCardOnTable.isEmpty()) {
                    listSuggestCards = listPlayers[gameTurn].getSuggestAttackCard(listCardOnTable);
                }
            } else {
                gameTurn = defenseTurn;
                if (listPlayers[gameTurn] != null) {
                    int suggesetCard = listPlayers[gameTurn].getSuggestDefenseCard(currentAttackCard, masterCard);
                    if (suggesetCard != -1) {
                        listSuggestCards.add(suggesetCard);
                    }
                }
            }
            tanResponse.sendGameTurn(gameTurn, currentAttackTurn, defenseTurn, lastBlock, listSuggestCards, finishRound, getListRegisters());
            isFighted = false;
            finishRound = 0;
        }

        if (isFinishMatch || numberPlayings <= 1) {
            onFinishMatch();
        }
    }

    private List<Integer> getListRegisters() {
        List<Integer> listRegisterState = new LinkedList<Integer>();
        for (int i = 0; i < maxPlayer; i++) {
            boolean isRegistered = false;
            for (Integer registerId : listRegisterAttack) {
                if (registerId.equals(i)) {
                    isRegistered = true;
                    break;
                }
            }
            if (isRegistered) {
                listRegisterState.add(1);
            } else {
                listRegisterState.add(0);
            }

        }
        return listRegisterState;
    }

    public TanPlayer getPlayerFight() {
        return listPlayers[gameTurn];
    }

    @Override
    protected void checkAllowPlay() {
        if (!Debug.isDebug) {
            for (int i = 0; i < maxPlayer; i++) {
                if (listPlayers[i] != null && listPlayers[i].getMoney() < betMoney * 5) {
                    tanResponse.sendPlayerKick(listPlayers[i].getName(), listPlayers[i].getSeatPos(), listPlayers[i].getUser());
                }
            }
        } else {
            for (int i = 0; i < maxPlayer; i++) {
                if (listPlayers[i] != null && listPlayers[i].getMoney() < 0) {
                    tanResponse.sendPlayerKick(listPlayers[i].getName(), listPlayers[i].getSeatPos(), listPlayers[i].getUser());
                }
            }
        }
    }

    @Override
    protected void sendPlayerKick(String name, int seatPos, User user) {
        this.tanResponse.sendPlayerKick(name, seatPos, user);
    }

    @Override
    public void updateDatabase() {
        if (!Debug.isDebug) {
            for (int i = 0; i < maxPlayer; i++) {
                if (listPlayers[i] != null) {
                    this.tanExtension.getDatabase().updateMoneyJoin(tanExtension.getRoomPrefix(), listPlayers[i].getName(), listPlayers[i].getMoney());
                }
            }
        }

    }

    @Override
    public TanPlayer[] getListPlayers() {
        return listPlayers;
    }

    @Override
    protected void sendTableInfo(String roomName, List<String> listNames, List<Integer> listPos, List<User> listUser) {
        this.tanResponse.sendTableInfo(roomName, listNames, listPos, listUser);
    }

    public boolean checkCard(int cardFight) {
        if (listCardOnTable.isEmpty()) {
            return true;
        } else {
            if (fightState == ATTACK) {
                for (Integer cardId : listCardOnTable) {
                    if (cardFight % 13 == cardId % 13) {
                        return true;
                    }
                }
            } else {
                if (currentAttackCard / 13 != masterCard / 13) {
                    if (cardFight / 13 == masterCard / 13) {
                        return true;
                    } else if (cardFight / 13 == currentAttackCard / 13
                            && getCardRank(cardFight) > getCardRank(currentAttackCard)) {
                        return true;
                    }
                } else if (cardFight / 13 == masterCard / 13
                        && getCardRank(cardFight) > getCardRank(currentAttackCard)) {
                    return true;
                }
            }
        }
        return false;
    }

    private int getCardRank(int cardId) {
        return (cardId - 1 + 13) % 13;
    }

    public void doFightAllCard() {
        if (listPlayers[gameTurn].getAttackState() == TanPlayer.DEFENSE) {
            setFinishRound();
        } else {
            listPlayers[gameTurn].setAttackState(TanPlayer.SKIP);
        }
        if (numberCardRemains <= 0) {
            int rank = getRankPlayer(gameTurn);
            tanResponse.sendFightAll(rank, gameTurn, numberPlayers - numberPlayings);
        }
    }

    public void setFinishRound() {
        finishRound = 1;
        currentAttackCard = -1;
        listPlayers[currentAttackTurn].setAttackState(TanPlayer.WAIT_ATTACK);
        listRegisterAttack.clear();
    }

    public boolean getIsFinishMatch() {
        return isFinishMatch;
    }

    private void findLastPlayer() {
        for (int i = 0; i < maxPlayer; i++) {
            {
                if (listPlayers[i] != null) {
                    if ((listPlayers[i].getState() == TanPlayer.PLAYING
                            && listPlayers[i].getState() != TanPlayer.FINISH)) {
                        listPlayers[i].setState(TanPlayer.FINISH);
                        tanResponse.sendFightAll(currentRank, i, numberPlayers - numberPlayings);
                        listPlayers[i].setRank(currentRank);
                        Debug.d("last player :" + listPlayers[i].getName() + ",rank :" + currentRank);
                        break;
                    }
                }
            }

        }
    }

    private void calculateMoneyChange() {
        winnerId = 0;
        long totalMoneyChange = 0;
        for (int i = 0; i < maxPlayer; i++) {
            if (listPlayers[i] != null) {
                int rank = listPlayers[i].getRank();
                if (rank == 0) {
                    winnerId = i;
                } else {
                    listPlayers[i].setMoneyChange(-betMoney * rank);
                    totalMoneyChange += betMoney * rank;
                }
            }
        }

        if (winnerId
                != -1 && listPlayers[winnerId] != null) {
            totalMoneyChange += penaltyMoney;
            listPlayers[winnerId].setMoneyChange(totalMoneyChange);
            penaltyMoney = 0;
        }
    }

    public void onFinishMatch() {
        Debug.d("on finish match");
        //find remain player
        findLastPlayer();
        calculateMoneyChange();

        List<Long> listMoneyResult = new LinkedList<Long>();
        List<Long> listPlayerMoney = new LinkedList<Long>();
        winnerId = -1;
        for (int i = 0; i < maxPlayer; i++) {
            if (listPlayers[i] != null && listPlayers[i].getState() == TanPlayer.FINISH) {
                long moneyChange = listPlayers[i].getMoneyChange();
                listMoneyResult.add(moneyChange);
                listPlayers[i].updateMoneChange();
                listPlayerMoney.add(listPlayers[i].getMoney());
                if (listPlayers[i].getRank() == 0) {
                    winnerId = i;
                }
            } else {
                listMoneyResult.add(-1l);
                listPlayerMoney.add(-1l);
            }
        }
        reset();
        tanResponse.sendFinishMatch(listMoneyResult, listPlayerMoney, winnerId, tableHost, numberPlayers);
        updateDatabase();
        checkAllowPlay();
    }

    private void reset() {
        canGetMoreCard = true;
        currentRank = 0;
        isPlay = false;
        numberPlayings = 0;
        isFinishMatch = false;
        listCardOnTable.clear();
        isFighted = false;
        for (int i = 0; i < maxPlayer; i++) {
            if (listPlayers[i] != null) {
                listPlayers[i].setState(TanPlayer.NOT_READY);
                listPlayers[i].resetCard();
                numberPlayings++;
            }
        }
        Debug.d("number playing when reset :" + numberPlayings);
    }

    public boolean isIsFighted() {
        return isFighted;
    }

    public void setCurrentCard(int cardFight) {
        isFighted = true;
        lastBlock = gameTurn;
        listCardOnTable.add(cardFight);
        if (fightState == ATTACK) {
            this.currentAttackCard = cardFight;
        } else {
            this.currentAttackCard = -1;
        }

    }

    public List<Integer> getListCardOnTable() {
        return listCardOnTable;
    }

    public void findNextAttack() {
        listPlayers[currentAttackTurn].setAttackState(TanPlayer.WAIT_ATTACK);
        currentAttackCard = -1;
        listRegisterAttack.clear();

    }

    public int getFightState() {
        return fightState;
    }

    public void genrateMasterCard() {
        masterCard = dealer.nextCard();
        Debug.d("master card :" + Card.getName(masterCard));
        tanResponse.sendMasterCard(gameTurn, masterCard, room.getUserList());
        numberCardRemains = dealer.getSize() + 1;
        Debug.d("card remain :" + numberCardRemains);
        tanResponse.sendNumberCardRemain(numberCardRemains, room.getUserList());
    }

    @Override
    public void doLoop() {
    }

    @Override
    public void doReady() {
        setIsHostTimeOut(true);
        tanResponse.sendTimeCount(tableHost);
    }

    @Override
    public void updateTableInfo(List<String> listNames, List<Long> listMoneys, List<Integer> listStates, Player player) {
        sendTableInfo(listNames, listMoneys, listStates, player, player.getUser());

        if (numberPlayings >= 1 && player.getSeatPos() >= 0) {
            sendUpdateTable(player.getUser(), player);
            sendUpdate();
        }
    }

    private void sendUpdateTable(User user, Player player) {
        List<User> listSend = room.getUserList();
        listSend.remove(user);
        tanResponse.sendUpdatePlayers(user.getName(), player.getMoney(), player.getSeatPos(), listSend);
    }

    private void sendUpdate() {
        String groupName = room.getGroupId();
        Room lobbyRoom = tanExtension.getParentZone().getRoomByName("The Lobby");
        List<User> listSend = lobbyRoom.getUserList();
        for (User u : listSend) {
            String groupView = (String) u.getProperty(Flag.GROUP_NAME);
            if (groupView.equals(groupName)) {
                tanResponse.sendUpdateTable(room.getName(), numberPlayings, room.getGroupId(), betMoney, u);
            }
        }
    }

    @Override
    public void updateNumberPlaying() {
        numberPlayings = 0;
        for (int i = 0; i < maxPlayer; i++) {
            if (listPlayers[i] != null
                    && (listPlayers[i].getState() == TanPlayer.PLAYING
                    || listPlayers[i].getState() == TanPlayer.FINISH)) {
                numberPlayings++;
            }
        }
    }

    public void doTimeOut(User user) {
        if (user.equals(listPlayers[gameTurn].getUser())) {
            TanPlayer p = listPlayers[gameTurn];
            if (listCardOnTable.isEmpty()) {
                int minCard = listPlayers[gameTurn].getMinCard(masterCard);
                setCurrentCard(minCard);
                p.removeCardInHand(minCard);
                tanResponse.sendFightCard(minCard, 1, gameTurn, room.getUserList());
                //check remain card
                if (p.getNumberCardInHands() <= 0) {
                    doFightAllCard();
                }

                nextTurn();
            } else {
                if (fightState == TanGame.ATTACK) {
                    p.setAttackState(TanPlayer.SKIP);
                    Debug.d(p.getName() + " stop attack");
                } else {
                    for (Integer cardAdd : listCardOnTable) {
                        p.addCard(cardAdd);
                    }
                    p.updateNumberCardInHand();
                    Debug.d(p.getName() + " en fold card");
                    logShowSet(p.getName(), listCardOnTable);
                    tanResponse.sendEnFoldCard(listCardOnTable, p.getSeatPos(), room.getUserList());
                    p.setAttackState(TanPlayer.DEFENSE_LOST);
                    findNextAttack();
                }
                nextTurn();
            }
        }
    }

    @Override
    public void updateNumberInRoom() {
        numberInRooms = 0;
        for (int i = 0; i < maxPlayer; i++) {
            if (listPlayers[i] != null) {
                numberInRooms++;
            }
        }
    }

    public int getNumberViews() {
        return numberPlayers - numberPlayings;
    }
}
